<template>
    <form
        class="form vue-form"
        @submit.prevent="submit"
    >
        <section
            class="card"
            role="region"
            aria-labelledby="hdr_edit_ls_config"
        >
            <div class="card-header text-bg-primary">
                <h2
                    id="hdr_edit_ls_config"
                    class="card-title"
                >
                    {{ $gettext('Edit Liquidsoap Configuration') }}
                </h2>
            </div>

            <info-card>
                <p class="card-text">
                    {{
                        $gettext('Using this page, you can customize several sections of the Liquidsoap configuration. This allows you to add advanced functionality to your station\'s AutoDJ.')
                    }}
                </p>
                <p class="card-text">
                    {{
                        $gettext('The editable text boxes are areas where you can insert custom configuration code. The non-editable sections are automatically generated by AzuraCast.')
                    }}
                </p>
                <p class="card-text">
                    {{
                        $gettext('This is an advanced feature and custom code is not officially supported by AzuraCast. You may break your station by adding custom code, but removing it should fix any issues.')
                    }}
                </p>
            </info-card>

            <loading :loading="isLoading" lazy>
                <div class="card-body">
                    <div class="buttons mb-3">
                        <a
                            class="btn btn-sm btn-secondary"
                            :href="exportUrl"
                            target="_blank"
                        >
                            {{ $gettext('Export Configuration') }}
                        </a>

                        <button class="btn btn-sm btn-secondary" @click.prevent="doImport">
                            {{ $gettext('Import Configuration') }}
                        </button>
                    </div>

                    <button
                        type="submit"
                        class="btn mb-2"
                        :class="(r$.$invalid) ? 'btn-danger' : 'btn-primary'"
                    >
                        {{ $gettext('Save Changes') }}
                    </button>

                    <form-fieldset
                        v-for="(row, index) in config"
                        :key="index"
                        class="mb-0"
                    >
                        <form-group-field
                            v-if="row.is_field"
                            :id="'form_edit_'+row.field_name"
                            :field="r$[row.field_name]"
                        >
                            <template #default="{id, model}">
                                <codemirror-textarea
                                    :id="id"
                                    v-model="model.$model"
                                    mode="liquidsoap"
                                />
                            </template>
                        </form-group-field>
                        <form-markup
                            v-else
                            :id="'form_section_'+index"
                        >
                            <pre class="typography-body-1">{{ row.markup ?? "" }}</pre>
                        </form-markup>
                    </form-fieldset>

                    <button
                        type="submit"
                        class="btn mt-2"
                        :class="(r$.$invalid) ? 'btn-danger' : 'btn-primary'"
                    >
                        {{ $gettext('Save Changes') }}
                    </button>
                </div>
            </loading>
        </section>
    </form>

    <import-modal
        ref="$importModal"
        :import-url="importUrl"
        @relist="() => relist()"
    />
</template>

<script setup lang="ts">
import FormFieldset from "~/components/Form/FormFieldset.vue";
import FormGroupField from "~/components/Form/FormGroupField.vue";
import FormMarkup from "~/components/Form/FormMarkup.vue";
import mergeExisting from "~/functions/mergeExisting";
import InfoCard from "~/components/Common/InfoCard.vue";
import {onMounted, ref, useTemplateRef} from "vue";
import {useMayNeedRestart} from "~/functions/useMayNeedRestart";
import {useAxios} from "~/vendor/axios";
import {useNotify} from "~/components/Common/Toasts/useNotify.ts";
import Loading from "~/components/Common/Loading.vue";
import CodemirrorTextarea from "~/components/Common/CodemirrorTextarea.vue";
import ImportModal from "~/components/Stations/LiquidsoapConfig/ImportModal.vue";
import {useResettableRef} from "~/functions/useResettableRef.ts";
import {useAppRegle} from "~/vendor/regle.ts";
import {StationBackendConfiguration} from "~/entities/ApiInterfaces.ts";
import {useApiRouter} from "~/functions/useApiRouter.ts";

const {getStationApiUrl} = useApiRouter();
const settingsUrl = getStationApiUrl('/liquidsoap-config');
const exportUrl = getStationApiUrl('/liquidsoap-config/export');
const importUrl = getStationApiUrl('/liquidsoap-config/import');

type ConfigSectionNames =
    | 'custom_config_top'
    | 'custom_config_pre_playlists'
    | 'custom_config_pre_live'
    | 'custom_config_pre_fade'
    | 'custom_config'
    | 'custom_config_bottom';

type ConfigRow = {
    is_field: true,
    field_name: ConfigSectionNames,
    markup?: never
} | {
    is_field: false,
    field_name?: never,
    markup: string
}

const config = ref<ConfigRow[]>([]);

type ConfigSections = Required<Pick<
    StationBackendConfiguration,
    ConfigSectionNames
>>

const sections = ref<string[]>([]);

const {record: form, reset: resetForm} = useResettableRef<ConfigSections>(() => ({
    custom_config_top: null,
    custom_config_pre_playlists: null,
    custom_config_pre_live: null,
    custom_config_pre_fade: null,
    custom_config: null,
    custom_config_bottom: null
}));

const {r$} = useAppRegle(
    form,
    {},
    {}
);

const isLoading = ref(true);

const {mayNeedRestart} = useMayNeedRestart();

const {axios} = useAxios();

const relist = async () => {
    isLoading.value = true;

    try {
        const {data} = await axios.get(settingsUrl.value);
        config.value = data.config;
        sections.value = data.sections;

        resetForm();
        r$.$reset();

        form.value = mergeExisting(form.value, data.contents);
    } finally {
        isLoading.value = false;
    }
};

onMounted(relist);

const {notifySuccess} = useNotify();

const submit = async () => {
    const {valid} = await r$.$validate();

    if (!valid) {
        return;
    }

    await axios({
        method: 'PUT',
        url: settingsUrl.value,
        data: form.value,
    });

    notifySuccess();
    mayNeedRestart();
    await relist();
}

const $importModal = useTemplateRef('$importModal');

const doImport = () => {
    $importModal.value?.open();
};
</script>
